package com.pxample.pemo.service;

import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.ByteString;
import com.pxample.api.CityScore;
import com.pxample.api.CityScore.CityScoreResponse;
import com.pxample.api.CityScore.CityScoreRequest;
import com.pxample.api.cityscoreGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.http.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@GrpcService
public class CityScoreService extends cityscoreGrpc.cityscoreImplBase {

    @Autowired
    private ValidationService validationService;

    @Autowired
    ThreadPoolTaskExecutor executor;

    @Autowired
    WebClient webClient;


    @Override
    public void calculateCityScore (CityScoreRequest cityScoreRequest, StreamObserver<CityScoreResponse> responseObserver) {
        int sleep = cityScoreRequest.getSleep();
        System.out.println("..................23232");
//        webClient.get().uri("http://127.0.0.1:8200/test").retrieve().bodyToMono(String.class).subscribe(resp->{
//            CityScoreResponse response = CityScoreResponse.newBuilder().setCityScore(1223).build();
//            responseObserver.onNext(response);
//            responseObserver.onCompleted();
//        });

        Map<String, String> map = new HashMap<>();
        map.put("aaa", "123");
//        String block = webClient.get().uri("http://127.0.0.1:8200/test?aaa={aaa}",map).retrieve().bodyToMono(String.class).block();
         webClient.get().uri("http://127.0.0.1:8200/test?aaa={aaa}",map).retrieve().bodyToMono(String.class).subscribe(resp->{
             CityScoreResponse response = CityScoreResponse.newBuilder().setCityScore(123).build();
             responseObserver.onNext(response);
             responseObserver.onCompleted();
         });

//        System.out.println(block);

        /*  int sync = cityScoreRequest.getServerSync();
        if (sync == 1){
            CityScoreResponse cityScoreResponse = CityScoreResponse.newBuilder()
                    .setCityScore(1234)
                    .build();
            responseObserver.onNext(cityScoreResponse);
            responseObserver.onCompleted();*/
//        }else {
                /*CompletableFuture.supplyAsync(()->{
                    if (sleep !=0){
                        try {
                            Thread.sleep(sleep);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    CityScoreResponse cityScoreResponse = CityScoreResponse.newBuilder()
                            .setCityScore(123)
                            .build();
                    return cityScoreResponse;
                },executor)
                        .thenAccept((response)->{
                            responseObserver.onNext(response);
                            responseObserver.onCompleted();
                        });*/
//            }
        }

    @Override
    public void newCityScore(CityScoreRequest request, StreamObserver<CityScoreResponse> responseObserver) {
        CityScoreResponse cityScoreResponse = CityScoreResponse.newBuilder()
                .setCityScore(123)
                .build();
        responseObserver.onNext(cityScoreResponse);
        responseObserver.onCompleted();
    }

    @Override
    public void asyncScore(CityScoreRequest request, StreamObserver<CityScoreResponse> responseObserver) {
        CompletableFuture.supplyAsync(()->{
            CityScoreResponse cityScoreResponse = CityScoreResponse.newBuilder()
                    .setCityScore(123)
                    .build();
            return cityScoreResponse;
        },executor)
                .thenAccept((response)->{
                    responseObserver.onNext(response);
                    responseObserver.onCompleted();
                });
    }


    @Autowired
    RestTemplate restTemplate;


    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Override
    public void upload(CityScore.FileUploadRequest request, StreamObserver<CityScore.FileUploadResponse> responseObserver) {
        ByteString byteString = request.getContent();
        MultipartFile file = new CustomMultipartFile(
                byteString.toByteArray(),
                "file",
                "example.jpg",
                "image/jpeg"
        );

        try {
        // 1. 准备请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        // 2. 准备请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

        body.add("file", new ByteArrayResource(file.getBytes()) {
            @Override
            public String getFilename() {
                return file.getOriginalFilename(); // 保持文件名
            }
        });
        // 3. 创建请求实体
        HttpEntity<MultiValueMap<String, Object>> requestEntity =
                new HttpEntity<>(body, headers);


            // 4. 发送请求
            ResponseEntity<JSONObject> response = restTemplate.exchange(
                    new URI("http://127.0.0.1:8200/uploadFile"),
                    HttpMethod.POST,
                    requestEntity,
                    JSONObject.class
            );

            CityScore.FileUploadResponse uploadResponse = CityScore.FileUploadResponse.newBuilder().setJson(ByteString.copyFromUtf8(response.toString())).build();
            responseObserver.onNext(uploadResponse);
            responseObserver.onCompleted();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


}
